﻿// Compiler.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "global.h"
#include"lexer.h"
#include"Grammar.h"
using namespace std;
extern SymbolTable symbolTable;



vector<LR1ItemSet> loadItemSetsFromFile(const string& filename) {
    vector<LR1ItemSet> itemSets;
    ifstream inFile(filename);
    if (!inFile) return itemSets;

    vector<string> currentSetLines;
    string line;
    while (getline(inFile, line)) {
        if (line == "====") {  // 使用====分隔不同项集
            if (!currentSetLines.empty()) {
                itemSets.push_back(LR1ItemSet::deserialize(currentSetLines));
                currentSetLines.clear();
            }
        }
        else {
            currentSetLines.push_back(line);
        }
    }

    // 处理最后一个项集
    if (!currentSetLines.empty()) {
        itemSets.push_back(LR1ItemSet::deserialize(currentSetLines));
    }

    return itemSets;
}

void saveItemSetsToFile(const string& filename, const vector<LR1ItemSet>& itemSets) {
    ofstream outFile(filename);
    for (const auto& itemSet : itemSets) {
        outFile << itemSet.serialize();
        outFile << "====\n";  // 分隔符
    }
}




int main()
{
    const string transFile = "trans.txt";
    const string itemSetsFile = "itemSets.txt";
	Grammar grammar("in.txt");

    grammar.computeFirstSets();
    //grammar.printFirstSets();






    // 构建LR(1)项集
    vector<LR1ItemSet> itemSets;


    // 尝试从文件读取
    itemSets = loadItemSetsFromFile(itemSetsFile);
    if (!itemSets.empty()) {
       // cout << "Loaded " << itemSets.size() << " item sets from file.\n";
        ifstream in(transFile);
        grammar.deserializeTransitions(in);
    }
    else {
        // 重新计算并保存
        itemSets = grammar.buildLR1ItemSets();
        saveItemSetsToFile("itemSets.txt", itemSets);
       // cout << "Saved " << itemSets.size() << " item sets to file.\n";
        // 保存Grammar状态
        ofstream out(transFile);
        grammar.serializeTransitions(out);
       // cout << "Saved grammar state to file.\n";
    }
//	vector<LR1ItemSet> itemSets = grammar.buildLR1ItemSets();

    //cout << "\nLR(1) Item Sets:\n";
    //for (const auto& itemSet : itemSets) {
    //    cout << itemSet.toString() << "\n";
    //}

    // 构建LR(1)分析表
    LR1ParsingTable table = grammar.buildLR1ParsingTable(itemSets);
    //table.print();
	/*system("pause");*/


	string sourceCode;
	string line;
	while (getline(cin, line)) {
		sourceCode += line + '\n';
	}
	Lexer lexer(sourceCode);

	bool success = grammar.parse(lexer, table); // Perform parsing

	// --- Output ---
	// Output is handled within grammar.parse() on success,
	// or "Syntax Error" is printed on failure.

	if (!success && !symbolTable.errorOccurred) {
		// If parse returned false but no specific error message was printed yet
		// (e.g., stack error, internal error), print the generic error.
		// Specific errors like undefined var, duplicate def should print themselves.
		// cout << "Syntax Error" << endl; // Already printed in most error paths now
	}


	//return success ? 0 : 1; // Return 0 on success, 1 on error
	return 0;
}

/*
double a;
{
 a=2.4*5;
}

*/